package com.neu.gulimall.search.thread;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadTest2 {

    public static ExecutorService service = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("main-----start-----");

//        CompletableFuture<Void> runAsync = CompletableFuture.runAsync(()->{
//            System.out.println("Thread002------start-----");
//            System.out.println("当前线程----->" + Thread.currentThread().getName());
//            int i = 10;
//            System.out.println("运行结果---->" + i/2);
//            System.out.println("Thread002------end-----");
//        },service);

//        CompletableFuture<Integer> runAsync = CompletableFuture.supplyAsync(()->{
//                System.out.println("Thread002------start-----");
//                System.out.println("当前线程----->" + Thread.currentThread().getName());
//                int i = 10/2;
//                System.out.println("运行结果---->" + i);
//                System.out.println("Thread002------end-----");
//                return i;
//        },service);
//        System.out.println("返回的结果是======"+runAsync.get());

        // 方法完成之后的感知
//        CompletableFuture<Integer> runAsync = CompletableFuture.supplyAsync(()->{
//            System.out.println("Thread002------start-----");
//            System.out.println("当前线程----->" + Thread.currentThread().getName());
//            int i = 10/0;
//            System.out.println("运行结果---->" + i);
//            System.out.println("Thread002------end-----");
//            return i;
//        },service).whenComplete((result,exception)->{
//            // 虽然能够得到异常信息，但是没法修改返回数据
//            System.out.println("异步任务成功完成了。。。。结果是====="+result+"===出现的异常是===="+exception);
//        }).exceptionally(throwable -> {
//            // 可以感知异常，同时返回默认数据
//            return 10;
//        });

        // 方法执行完成之后的处理
//        CompletableFuture<Integer> runAsync = CompletableFuture.supplyAsync(()->{
//            System.out.println("Thread002------start-----");
//            System.out.println("当前线程----->" + Thread.currentThread().getName());
//            int i = 10/2;
//            System.out.println("运行结果---->" + i);
//            System.out.println("Thread002------end-----");
//            return i;
//        },service).handle((res,exp)->{
//            if (res != null){ // 返回结果不为空，说明没有出现异常
//                return res*2;
//            }
//            if (exp != null){ // 表示出现了异常
//                return 0;
//            }
//            return 0;
//        });

        /**
         *  线程串行化
         *  1、thenRunAsync ---- 不能获取到上一个线程的执行结果且无返回值
         *      .thenRunAsync(() -> {
         *             System.out.println("任务2启动了-------");
         *         }, service);
         *  2、thenAcceptAsync ---- 能够获取到上一步的执行结果，但无返回值
         *      .thenAcceptAsync((res)->{
         *             System.out.println("任务2启动了-------上一步的处理结果是-------"+res);
         *         },service);
         *  3、thenApplyAsync ----- 能够接收上一步的处理结果，且有返回值
         *      .thenApplyAsync((res)->{
         *             System.out.println("任务2启动了-------上一步的处理结果是-------"+res);
         *
         *             return res*2;
         *         },service);
         */
//        CompletableFuture<Integer> runAsync = CompletableFuture.supplyAsync(() -> {
//            System.out.println("Thread002------start-----");
//            System.out.println("当前线程----->" + Thread.currentThread().getName());
//            int i = 10 / 2;
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            System.out.println("运行结果---->" + i);
//            System.out.println("Thread002------end-----");
//            return i;
//        }, service).thenApplyAsync((res)->{
//            System.out.println("任务2启动了-------上一步的处理结果是-------"+res);
//
//            return res*2;
//        },service);


        CompletableFuture<Object> future1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("Thread001------start-----");
            System.out.println("当前线程----->" + Thread.currentThread().getName());
            int i = 10 / 2;
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("运行结果---->" + i);
            System.out.println("Thread001------end-----");
            return i;
        }, service);

        CompletableFuture<Object> future2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("Thread002------start-----");

            System.out.println("Thread002------end-----");
            return "hello";
        }, service);

        /**
         *  组合两个任务，两个都完成
         */
//        future1.runAfterBothAsync(future2,()->{   // 不能接收结果且无返回值
//            System.out.println("线程3开始");
//        },service);

//        future1.thenAcceptBothAsync(future2,(f1,f2)->{ // 能接收结果且无返回值
//            System.out.println("线程3开始=====f1====="+f1+"======="+f2);
//        },service);

//        CompletableFuture<String> future = future1.thenCombineAsync(future2, (f1, f2) -> {  //能接收结果且有返回值
//            return f1 + "========" + f2 + "hahaha";
//        }, service);

        /**
         *  组合两个任务，只要有一个完成，就执行任务3
         */
//        future1.runAfterEitherAsync(future2,()->{   // 不能接收结果且无返回值
//            System.out.println("线程3开始");
//        },service);

//        future1.acceptEitherAsync(future2,(res)->{ //能接收结果但 无返回值
//            System.out.println("线程3开始====返回结果是===="+ res );
//        },service);

        CompletableFuture<String> future = future1.applyToEitherAsync(future2, (res) -> {
            System.out.println("线程3开始");
            return res.toString() + "hhhhhh";
        }, service);

        System.out.println("返回的结果是======"+future.get());

        System.out.println("main-----end-----" );

    }
}
